CI/CDでnpm ciする際は ~/.npm をキャッシュしよう
現在自分が担当しているプロジェクトでは、GitHub Acitionsを利用してデプロイを行っています。
npm ci
を使ってパッケージのインストールが行われていましたが、 その際に node_modules
をキャッシュしていて意味がない状態となっていました。
- name: Cache Node modules uses: actions/cache@v2 with: path: hoge/node_modules key: ${{ runner.os }}-node_modules-${{ hashFiles('**/package-lock.json') }} - name: Build hoge run: | npm ci npm run build working-directory: hoge
これは修正せねば!ということで、調べると npm ci
する際は ~/.npm
をキャッシュするのが良さそうだったので、備忘も兼ねてまとめておきます。
そもそも何が問題なのか?
npm install
と npm ci
は、どちらもパッケージをインストールするためのコマンドです。
npm install
は package.json
を参照して依存関係をインストールするため、パッケージのバージョン指定に「メジャーバージョンのみ固定」などの幅がある場合、インストールのタイミングによってバージョンの違いが発生することがあります。
実際にインストールされたバージョンが package-lock.json
に記されます。
npm ci
は、package-lock.json
を参照して依存関係をインストールするため、package-lock.json
が作成された時点のバージョンのパッケージをインストールすることが可能です。
CI/CDなどで毎回パッケージがインストールされる場合は、npm ci
コマンドを使い package-lock.json
からパッケージのインストールを行うことで、開発時とデプロイ時のバージョンの差異を無くすことができます。
npm ci
でパッケージのインストールをした場合は node_modules
ディレクトリは毎回新しく構築されるため、キャッシュしていても意味がありませんでした。
If a node_modules is already present, it will be automatically removed before npm ci begins its install.
~/.npm
をキャッシュする
npm ciのドキュメントでは、 Travis CIを使う際に ~/.npm
をキャッシュする例が記されていました。
# .travis.yml install: - npm ci # keep the npm cache around to speed up installs cache: directories: - "$HOME/.npm"
npmは、パッケージをインストールする際に ~/.npm
にキャッシュを保存し、同じパッケージが必要になった場合に、ネットワークへのアクセスなくインストールが可能です。
そのため、 npm ci
を行う場合でも ~/.npm
をキャッシュすれば、インストールの高速化を図ることができます。
よって、こんな雰囲気に修正しました。
- name: Cache npm dir uses: actions/cache@v2 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Build hoge run: | npm ci npm run build working-directory: hoge
めでたしめでたし